package com.googlecode.animator.controller
{
	
	import com.googlecode.utils.UniqueID;
	import com.googlecode.data.ProjectConstants;
	
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.utils.Dictionary;
	
	import mx.controls.Alert;
	
	import org.puremvc.as3.multicore.interfaces.INotification;
		
	/**
	 * Responds to user saving the project. 
	 * @author USER
	 * 
	 */
	public class PackageProjectCommand extends BaseCommand
	{
		protected var _uniqueID:UniqueID = new UniqueID();
		protected var _list:Array = [];
		protected var _unique:Dictionary = new Dictionary();
		
		/**
		 * Executes command. 
		 * @param notification
		 * 
		 */
		override public function execute(notification:INotification):void
		{
			super.execute(notification);
			
			var file:File = new File();
			var projectXML:XML = settings.getProjectXML();
			
			// create an project folder
			file.url = (notification.getBody() as String);

			if(!file.isDirectory)
			{
				try
				{
					file.createDirectory();
				}catch(err:Error)
				{
					trace("Attempting to create project directory \n" + err);
				}
			}
			
			var assetsDirectory:File = file.resolvePath("assets");
			
			
			if(!assetsDirectory.isDirectory)
			{
				try
				{
					assetsDirectory.createDirectory();
				}catch(err:Error)
				{
					trace("Attempting to create assets directory \n" + err);
				}
				
			}
			
			
			// now use xml to work out new file paths. Use dictionary to ensure no duplicates
			
			for each(var path:XML in projectXML..filePath)
			{
				_unique[path.toString()] = getRelativePath(path.toString());			
			}
			
			
			var count:uint = 0;
			var asset:File;
			var destination:File;

			for each(path in projectXML..filePath)
			{
				// check file 
				if(path.@isRelative == "false")
				{
					
					asset = new File();
					asset.url = path;	
				
				}else if(path.toString().substr(0,ProjectConstants.PROJECT_ROOT.length) == ProjectConstants.PROJECT_ROOT)
				{
					asset = File.applicationDirectory;
					asset = asset.resolvePath(path);
				
				}else if(path.@isRelative == "true")
				{	
					asset = new File();
					asset.url = getCurrentDirectory();
					asset = asset.resolvePath(path);
					
				}else
				{
					count++;
					continue;
				}
				
				if(path.@isRelative == "true")
				{
					var testFile:File = file.resolvePath(path);
					
					if(testFile.exists)
					{
						count++;
						continue;
					}
				}
				destination = assetsDirectory.resolvePath(_unique[path.toString()]);
				copyTo(asset, destination);

				projectXML..filePath[count] = "assets/" + _unique[path.toString()];
				path.@isRelative = "true";

				
				count++;		
			}
			
			var assetFile:File = File.applicationDirectory;
			// load the player files
			var js:File = assetFile.resolvePath(ProjectConstants.JS_PATH);
			destination = file.resolvePath("AC_OETags.js");
			copyTo(js, destination);
						
			var player:File = assetFile.resolvePath(ProjectConstants.PLAYER_SWF_PATH);
			destination = file.resolvePath("Animator3DPlayer.swf");
			copyTo(player, destination);
			
			var ppi:File = assetFile.resolvePath(ProjectConstants.INSTALL_SWF_PATH);
			destination = file.resolvePath("playerProductInstall.swf");
			copyTo(ppi, destination);
			
			var html:File = assetFile.resolvePath(ProjectConstants.HTML_PATH);
			var fileStream:FileStream = new FileStream();
			
			try
			{
				fileStream.open(html, FileMode.READ);			
				var htmlText:String = fileStream.readUTFBytes(4228);
			}catch(err:Error)
			{
				trace("Opening Shell.html \n" + err);
				
				Alert.show("Please try again.");
				
				fileStream.close();
				
				return;
			}
			
			
			fileStream.close();

			var widthTxt:RegExp = /stageWidth/g;
			var heightTxt:RegExp = /stageHeight/g;

			htmlText = htmlText.replace(widthTxt, String(settings.stageWidth));
			htmlText = htmlText.replace(heightTxt, String(settings.stageHeight));
			

			//destination = file.resolvePath("Shell.html");
			//copyTo(html, destination);
			 
			
			var SWF:File = assetFile.resolvePath(ProjectConstants.SHELL_SWF_PATH);
			destination = file.resolvePath("Shell.swf");
			copyTo(SWF, destination);

			file.url = (notification.getBody() as String) + "/Shell.html";
			
			// if Shell.html exists, delete
			/* if(file.exists)
			{
				file.deleteFile();
			} */

			try
			{	
				fileStream.open(file, FileMode.WRITE);
				fileStream.writeUTFBytes(htmlText);

			}catch(err:Error)
			{
				trace("Writing Shell.html \n" + err);
				
				Alert.show("Shell.html in use. Close and try again.");
				
				fileStream.close();
				
				return;
			}
			
			
			fileStream.close();
			
			// write the project XML
			file.url = (notification.getBody() as String) + "/project.xml";
			
			// if project.xml exists, delete file
			/* if(file.exists)
			{
				file.deleteFile();
			} */
			
			try
			{	
				fileStream.open(file, FileMode.WRITE);
				fileStream.writeUTFBytes(projectXML);

			}catch(err:Error)
			{
				trace("Writing project.xml \n" + err);
				
				Alert.show("project.xml in use. Close and try again.");
				
				fileStream.close();
				
				return;
			}						
			
			fileStream.close();	
			
		}
		
		protected function getRelativePath(absolute:String):String
		{
			var ext:String = absolute.split(".").pop();

			return _uniqueID.generateID()  + "." + ext;
		}
		
		protected function copyTo(source:File, destination:File):void
		{
			try
			{
				if(!destination.exists)
				{
					source.copyTo(destination);
				}
			}catch(err:Error)
			{
				trace("Copy to\n" + err);
			}
		}
		
		protected function getCurrentDirectory():String
		{
			var file:File = new File();
			file.url = settings.savePath;
			
			return file.parent.url;
		}
	}
}